package com.tyjt.vehfinder.util;

import com.tyjt.common.Constants;
import com.tyjt.common.GridInfo;
import com.tyjt.common.GridUtil;
import com.tyjt.common.enums.PubTypeEnum;
import com.tyjt.common.mqtt.EmqxUtil;
import com.tyjt.common.redis.HashTagUtil;
import com.tyjt.proto.PubDataDTO;
import com.tyjt.vehfinder.core.actor.BsmMsg;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;

@Component
@Slf4j
public class PubUtil {

    @Resource
    private DefaultRedisScript<List> redisGetDataScript;
    @Resource
    RedisTemplate<String, byte[]> binaryRedisTemplate;

    public void pub(BsmMsg bsm, String msgType, GridInfo posGrid) {
        String companyId = bsm.getCompanyId();
        String vehId = bsm.getVehId();
        final String gridX = String.valueOf(posGrid.getX());
        final String gridY = String.valueOf(posGrid.getY());
        //  下发topic
        String topic = Constants.CLOUD_2_VEH_TOPIC + companyId + Constants.EMQ_TOPIC_SEPARATOR + vehId;
        String hashTag = HashTagUtil.genHashTag(companyId,msgType);
        //  查询group  grid:{companyId:msgType}:x-y
        String redisSetKey = Constants.REDIS_GRID_PREFIX + hashTag +
                Constants.REDIS_KEY_SEPARATOR + gridX + Constants.REDIS_KEY_GRID_SEPARATOR + gridY;

        // 执行 Lua 脚本
        List<byte[]> validData = (List<byte[]>) binaryRedisTemplate.execute(
                redisGetDataScript,
                Collections.singletonList(redisSetKey)
        );

        // 第一个元素是有效数据的列表
        double minDis = Double.MAX_VALUE;
        PubDataDTO.PubData closestPubData = null;
        byte[] closestPubDataByte = null;
        for (byte[] value : validData) {

            try {
                PubDataDTO.PubData pubData = PubDataDTO.PubData.parseFrom(value);
                double dist_m = GridUtil.haversineDistance(bsm.getBsm().getLongitude(), bsm.getBsm().getLatitude(),
                        pubData.getMeta().getLongitude(), pubData.getMeta().getLatitude());
                if (dist_m <= minDis) {
                    minDis = dist_m;
                    closestPubData = pubData;
                    closestPubDataByte = value;
                }
            } catch (Exception e) {
                log.error("数据解析错误 redis key {}", redisSetKey);
            }
        }
        if (closestPubData != null) {
            if (closestPubData.getMeta().getPubType() == PubTypeEnum.ALL.getValue()) {
                EmqxUtil.sendMsg(topic, closestPubDataByte);
                System.out.println("发出时间" + System.currentTimeMillis());
            } else if (closestPubData.getMeta().getPubType() == PubTypeEnum.PAY_LOAD.getValue()) {
                EmqxUtil.sendMsg(topic, closestPubData.getPayload().toByteArray());
            }
        } else {
            log.error("不在范围内");
        }
    }


}
